API Reference¶
Auto-generated API documentation for the harombe Python package. This reference is generated from docstrings in the source code using mkdocstrings.
Core Modules¶
Agent¶
The ReAct agent loop and runtime for autonomous task execution.
harombe.agent
¶
ReAct agent loop for autonomous task execution.
This module implements the Reasoning + Acting (ReAct) pattern where the agent alternates between reasoning about what to do and executing tool calls. The loop continues until the task is complete or the step limit is reached.
Usage::
from harombe.agent.loop import Agent
from harombe.llm.ollama import OllamaClient
from harombe.tools.registry import get_enabled_tools
llm = OllamaClient(model="qwen2.5:7b")
tools = get_enabled_tools(shell=True, filesystem=True)
agent = Agent(llm=llm, tools=tools)
response = await agent.run("Analyze this file")
DelegationContext
dataclass
¶
Tracks the delegation chain from root agent to current agent.
Enforces max_depth and detects cycles (no agent name may appear twice in the chain).
Source code in src/harombe/agent/delegation.py
depth
property
¶
Current delegation depth.
can_delegate(target_name)
¶
Check if delegation to the target agent is allowed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_name
|
str
|
Name of the agent to delegate to |
required |
Returns:
| Type | Description |
|---|---|
tuple[bool, str]
|
Tuple of (allowed, reason_string) |
Source code in src/harombe/agent/delegation.py
child_context(agent_name)
¶
Create a child context for a delegated agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str
|
Name of the current agent being delegated to |
required |
Returns:
| Type | Description |
|---|---|
DelegationContext
|
New DelegationContext with extended chain |
Source code in src/harombe/agent/delegation.py
Agent
¶
ReAct agent with tool calling capabilities.
Source code in src/harombe/agent/loop.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | |
__init__(llm, tools, max_steps=10, system_prompt='You are a helpful AI assistant.', confirm_dangerous=True, confirm_callback=None, cluster_manager=None, memory_manager=None, mcp_manager=None, session_id=None, enable_rag=False, rag_top_k=5, rag_min_similarity=0.7)
¶
Initialize the agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
llm
|
LLMClient
|
LLM client for generating responses |
required |
tools
|
list[Tool]
|
List of available tools |
required |
max_steps
|
int
|
Maximum reasoning steps before forcing final answer |
10
|
system_prompt
|
str
|
System prompt for the agent |
'You are a helpful AI assistant.'
|
confirm_dangerous
|
bool
|
Whether to require confirmation for dangerous tools |
True
|
confirm_callback
|
Callable[[str, str, dict[str, Any]], bool] | None
|
Function called for dangerous tool confirmation. Takes (tool_name, description, args) -> bool. If None and confirm_dangerous=True, auto-denies dangerous tools. |
None
|
cluster_manager
|
Optional[ClusterManager]
|
Optional cluster manager for distributed routing |
None
|
memory_manager
|
Optional[MemoryManager]
|
Optional memory manager for conversation persistence |
None
|
mcp_manager
|
Optional[MCPManager]
|
Optional MCP manager for external tool servers |
None
|
session_id
|
str | None
|
Session ID for loading/saving conversation history |
None
|
enable_rag
|
bool
|
Enable retrieval-augmented generation from semantic memory |
False
|
rag_top_k
|
int
|
Number of similar messages to retrieve for RAG |
5
|
rag_min_similarity
|
float
|
Minimum similarity threshold for RAG retrieval |
0.7
|
Source code in src/harombe/agent/loop.py
run(user_message)
async
¶
Run the agent on a user message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_message
|
str
|
User's input message |
required |
Returns:
| Type | Description |
|---|---|
str
|
Agent's final response |
Source code in src/harombe/agent/loop.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
AgentState
¶
Maintains conversation state for the agent.
Source code in src/harombe/agent/loop.py
__init__(system_prompt)
¶
Initialize agent state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_prompt
|
str
|
System message for the agent |
required |
add_user_message(content)
¶
Add a user message to the conversation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
str
|
User message content |
required |
add_assistant_message(response)
¶
Add an assistant response to the conversation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
CompletionResponse
|
LLM completion response |
required |
Source code in src/harombe/agent/loop.py
add_tool_result(tool_call_id, tool_name, result)
¶
Add a tool execution result to the conversation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_call_id
|
str
|
ID of the tool call |
required |
tool_name
|
str
|
Name of the tool that was executed |
required |
result
|
str
|
Tool execution result |
required |
Source code in src/harombe/agent/loop.py
AgentBlueprint
dataclass
¶
Blueprint for creating an agent instance.
This stores the configuration needed to create a fresh Agent. Each delegation creates a new Agent from this blueprint.
Source code in src/harombe/agent/registry.py
AgentRegistry
¶
Registry of named agent blueprints.
Agents are registered by name. The registry stores blueprints, not live instances — each delegation creates a fresh Agent.
Source code in src/harombe/agent/registry.py
names
property
¶
List all registered agent names.
register(blueprint)
¶
Register an agent blueprint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blueprint
|
AgentBlueprint
|
Agent blueprint to register |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If an agent with the same name already exists |
Source code in src/harombe/agent/registry.py
get(name)
¶
Get an agent blueprint by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Agent name |
required |
Returns:
| Type | Description |
|---|---|
AgentBlueprint
|
AgentBlueprint instance |
Raises:
| Type | Description |
|---|---|
KeyError
|
If agent not found |
Source code in src/harombe/agent/registry.py
has(name)
¶
build_agent_registry(agent_configs)
¶
Create an AgentRegistry from configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_configs
|
list[NamedAgentConfig]
|
List of named agent configurations |
required |
Returns:
| Type | Description |
|---|---|
AgentRegistry
|
Populated AgentRegistry |
Source code in src/harombe/agent/builder.py
create_root_delegation_context(config)
¶
Create the root delegation context from config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
HarombeConfig
|
Harombe configuration |
required |
Returns:
| Type | Description |
|---|---|
DelegationContext
|
Root DelegationContext with max_depth from config |
Source code in src/harombe/agent/builder.py
options: show_root_heading: true members_order: source
Memory¶
Conversation persistence, semantic search, and RAG.
harombe.memory
¶
Conversation memory system for harombe.
Provides SQLite-backed conversation persistence with session management, token-based context windowing, and optional semantic search via vector embeddings. When combined with ChromaDB and sentence-transformers, enables Retrieval-Augmented Generation (RAG) for context-aware agent responses.
Components:
- :class:
MemoryManager- High-level API for session and message management - :class:
MemoryStorage- SQLite storage backend with WAL mode
MemoryManager
¶
High-level memory management interface with optional semantic search.
Source code in src/harombe/memory/manager.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 | |
__init__(storage_path, max_history_tokens=4096, embedding_client=None, vector_store=None)
¶
Initialize memory manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
storage_path
|
str | Path
|
Path to SQLite database |
required |
max_history_tokens
|
int
|
Maximum tokens to load from history |
4096
|
embedding_client
|
EmbeddingClient | None
|
Optional embedding client for semantic search |
None
|
vector_store
|
VectorStore | None
|
Optional vector store for semantic search |
None
|
Source code in src/harombe/memory/manager.py
create_session(system_prompt, metadata=None, session_id=None)
¶
Create a new conversation session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_prompt
|
str
|
System prompt for this session |
required |
metadata
|
SessionMetadata | None
|
Optional session metadata |
None
|
session_id
|
str | None
|
Optional custom session ID (generates UUID if not provided) |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Session ID |
Source code in src/harombe/memory/manager.py
get_session(session_id)
¶
Get session information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
SessionRecord | None
|
Session record or None if not found |
save_message(session_id, message)
¶
Save a message to a session.
If semantic search is enabled, also embeds and stores in vector store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
message
|
Message
|
Message to save |
required |
Returns:
| Type | Description |
|---|---|
int
|
Message ID |
Source code in src/harombe/memory/manager.py
wait_for_pending_embeddings()
async
¶
Wait for all pending embedding tasks to complete.
This is primarily for testing to ensure embeddings are indexed before performing searches.
Source code in src/harombe/memory/manager.py
load_history(session_id, max_tokens=None)
¶
Load conversation history for a session.
Loads the most recent messages that fit within token limit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
max_tokens
|
int | None
|
Maximum tokens to load (uses default if None) |
None
|
Returns:
| Type | Description |
|---|---|
list[Message]
|
List of messages in chronological order |
Source code in src/harombe/memory/manager.py
get_recent_messages(session_id, count=10)
¶
Get the N most recent messages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
count
|
int
|
Number of messages to retrieve |
10
|
Returns:
| Type | Description |
|---|---|
list[Message]
|
List of recent messages in chronological order |
Source code in src/harombe/memory/manager.py
list_sessions(limit=10, offset=0)
¶
List recent sessions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int
|
Maximum number of sessions to return |
10
|
offset
|
int
|
Number of sessions to skip |
0
|
Returns:
| Type | Description |
|---|---|
list[SessionRecord]
|
List of sessions ordered by most recent activity |
Source code in src/harombe/memory/manager.py
delete_session(session_id)
¶
Delete a session and all its messages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if session was deleted, False if not found |
Source code in src/harombe/memory/manager.py
clear_history(session_id)
¶
Clear all messages from a session (but keep the session).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of messages deleted |
Source code in src/harombe/memory/manager.py
get_message_count(session_id)
¶
Get the total number of messages in a session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
int
|
Message count |
Source code in src/harombe/memory/manager.py
prune_old_sessions(days=30)
¶
Delete sessions older than specified days.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
days
|
int
|
Delete sessions not updated in this many days |
30
|
Returns:
| Type | Description |
|---|---|
int
|
Number of sessions deleted |
Source code in src/harombe/memory/manager.py
session_exists(session_id)
¶
Check if a session exists.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if session exists |
get_or_create_session(session_id, system_prompt, metadata=None)
¶
Get an existing session or create a new one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
system_prompt
|
str
|
System prompt (used if creating new session) |
required |
metadata
|
SessionMetadata | None
|
Session metadata (used if creating new session) |
None
|
Returns:
| Type | Description |
|---|---|
tuple[str, bool]
|
Tuple of (session_id, created) where created is True if new session |
Source code in src/harombe/memory/manager.py
search_similar(query, top_k=5, session_id=None, min_similarity=None)
async
¶
Search for semantically similar messages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Query text to search for |
required |
top_k
|
int
|
Number of results to return |
5
|
session_id
|
str | None
|
Optional session to limit search to |
None
|
min_similarity
|
float | None
|
Optional minimum similarity threshold (0-1) |
None
|
Returns:
| Type | Description |
|---|---|
list[Message]
|
List of similar messages ordered by relevance |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If semantic search is not enabled |
Source code in src/harombe/memory/manager.py
get_relevant_context(query, max_tokens=2048, session_id=None)
async
¶
Get relevant context for a query, limited by token budget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Query text |
required |
max_tokens
|
int
|
Maximum tokens of context to return |
2048
|
session_id
|
str | None
|
Optional session to limit search to |
None
|
Returns:
| Type | Description |
|---|---|
list[Message]
|
List of relevant messages within token budget |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If semantic search is not enabled |
Source code in src/harombe/memory/manager.py
backfill_embeddings(session_id=None, batch_size=100)
¶
Backfill embeddings for existing messages.
Useful when enabling semantic search on existing conversation history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str | None
|
Optional session to limit backfill to (None = all sessions) |
None
|
batch_size
|
int
|
Number of messages to process at once |
100
|
Returns:
| Type | Description |
|---|---|
int
|
Number of messages embedded |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If semantic search is not enabled |
Source code in src/harombe/memory/manager.py
MemoryStorage
¶
SQLite-based storage for conversation memory.
Source code in src/harombe/memory/storage.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | |
__init__(db_path)
¶
Initialize storage with database path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
db_path
|
str | Path
|
Path to SQLite database file |
required |
Source code in src/harombe/memory/storage.py
create_session(session_id, system_prompt, metadata=None)
¶
Create a new conversation session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Unique session identifier |
required |
system_prompt
|
str
|
System prompt for this session |
required |
metadata
|
SessionMetadata | None
|
Optional session metadata |
None
|
Returns:
| Type | Description |
|---|---|
SessionRecord
|
Created session record |
Source code in src/harombe/memory/storage.py
get_session(session_id)
¶
Get a session by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
SessionRecord | None
|
Session record or None if not found |
Source code in src/harombe/memory/storage.py
update_session_activity(session_id)
¶
Update the last activity timestamp for a session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Source code in src/harombe/memory/storage.py
save_message(message)
¶
Save a message to storage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
MessageRecord
|
Message record to save |
required |
Returns:
| Type | Description |
|---|---|
int
|
Message ID assigned by database |
Source code in src/harombe/memory/storage.py
load_messages(session_id, limit=None, offset=0)
¶
Load messages for a session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
limit
|
int | None
|
Maximum number of messages to return |
None
|
offset
|
int
|
Number of messages to skip |
0
|
Returns:
| Type | Description |
|---|---|
list[Message]
|
List of messages in chronological order |
Source code in src/harombe/memory/storage.py
get_message_count(session_id)
¶
Get the total number of messages in a session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
int
|
Message count |
Source code in src/harombe/memory/storage.py
list_sessions(limit=10, offset=0)
¶
List recent sessions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int
|
Maximum number of sessions to return |
10
|
offset
|
int
|
Number of sessions to skip |
0
|
Returns:
| Type | Description |
|---|---|
list[SessionRecord]
|
List of sessions ordered by most recent activity |
Source code in src/harombe/memory/storage.py
delete_session(session_id)
¶
Delete a session and all its messages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if session was deleted, False if not found |
Source code in src/harombe/memory/storage.py
prune_old_sessions(days)
¶
Delete sessions older than specified days.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
days
|
int
|
Delete sessions not updated in this many days |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of sessions deleted |
Source code in src/harombe/memory/storage.py
clear_messages(session_id)
¶
Clear all messages from a session (but keep the session).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of messages deleted |
Source code in src/harombe/memory/storage.py
options: show_root_heading: true members_order: source
Security¶
Defense-in-depth security layer: MCP Gateway, audit logging, credential management, network isolation, HITL gates.
harombe.security
¶
Defense-in-depth security layer for harombe.
Implements the Capability-Container Pattern where every tool runs in its own isolated container. The agent communicates through an MCP Gateway and never directly touches raw credentials, host filesystems, or unrestricted networks.
Components:
- MCP Gateway (:class:
MCPGateway) - Centralized routing and security enforcement - Container Management (:class:
DockerManager) - Container lifecycle with resource limits - Audit Logging (:class:
AuditLogger, :class:AuditDatabase) - Immutable event trail with redaction - Credential Vault (:class:
HashiCorpVault, :class:SOPSBackend, :class:EnvVarBackend) - Multi-backend secrets - Secret Scanning (:class:
SecretScanner) - Pattern and entropy-based credential detection - Network Isolation (:class:
EgressFilter, :class:NetworkIsolationManager) - Default-deny egress - HITL Gates (:class:
HITLGate, :class:RiskClassifier) - Risk-based approval workflows - Browser Container (:class:
BrowserContainerManager) - Pre-authenticated browser automation - Sandbox (:class:
SandboxManager) - gVisor-based code execution sandbox - Monitoring (:class:
SecurityDashboard, :class:AlertRuleEngine, :class:SIEMIntegrator) - Observability - Compliance (:class:
ComplianceReportGenerator) - SOC 2, GDPR, PCI DSS report generation
Alert
¶
Bases: BaseModel
A generated alert.
Source code in src/harombe/security/alert_rules.py
AlertCondition
¶
Bases: BaseModel
A single condition that an event must match.
Source code in src/harombe/security/alert_rules.py
AlertRule
¶
Bases: BaseModel
An alert rule definition.
Source code in src/harombe/security/alert_rules.py
AlertRuleEngine
¶
Evaluates audit events against alert rules and dispatches notifications.
Supports: - Field matching with multiple operators - Windowed counting rules (N events in T seconds) - Alert deduplication with configurable cooldown - Multiple notification channels per rule - Statistics tracking
Usage
engine = AlertRuleEngine() engine.add_notifier(SlackNotifier(webhook_url="...")) engine.add_notifier(EmailNotifier(to_addresses=["security@example.com"]))
Evaluate an event¶
alerts = await engine.evaluate(audit_event)
Source code in src/harombe/security/alert_rules.py
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 | |
rules
property
¶
Get configured rules.
__init__(rules=None)
¶
Initialize alert rule engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rules
|
list[AlertRule] | None
|
Alert rules. If None, uses default rules. |
None
|
Source code in src/harombe/security/alert_rules.py
add_rule(rule)
¶
remove_rule(rule_name)
¶
add_notifier(notifier)
¶
remove_notifier(channel)
¶
evaluate(event)
async
¶
Evaluate an event against all rules.
Returns list of alerts that were triggered and sent.
Source code in src/harombe/security/alert_rules.py
get_stats()
¶
reset_windows()
¶
AlertSeverity
¶
EmailNotifier
¶
Bases: Notifier
Send alerts via email.
Source code in src/harombe/security/alert_rules.py
send(alert)
async
¶
Send alert via email.
In production, this would use aiosmtplib. For now, it formats the email payload and returns success (integration point for real SMTP).
Source code in src/harombe/security/alert_rules.py
NotificationChannel
¶
NotificationResult
¶
Notifier
¶
Base class for notification channels.
Source code in src/harombe/security/alert_rules.py
PagerDutyNotifier
¶
Bases: Notifier
Send alerts via PagerDuty Events API.
Source code in src/harombe/security/alert_rules.py
send(alert)
async
¶
Send alert via PagerDuty.
Only sends if alert severity meets minimum threshold.
Source code in src/harombe/security/alert_rules.py
SlackNotifier
¶
Bases: Notifier
Send alerts via Slack webhook.
Source code in src/harombe/security/alert_rules.py
send(alert)
async
¶
Send alert via Slack webhook.
In production, this would POST to the webhook URL.
Source code in src/harombe/security/alert_rules.py
AuditDatabase
¶
SQLite-based audit log database.
Thread-safe database operations for audit logging. Supports async writes, retention policies, and efficient queries.
Source code in src/harombe/security/audit_db.py
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 | |
__init__(db_path='~/.harombe/audit.db', retention_days=90)
¶
Initialize audit database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
db_path
|
str | Path
|
Path to SQLite database file |
'~/.harombe/audit.db'
|
retention_days
|
int
|
Number of days to retain audit logs |
90
|
Source code in src/harombe/security/audit_db.py
log_event(event)
¶
Log an audit event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
AuditEvent
|
Audit event to log |
required |
Source code in src/harombe/security/audit_db.py
log_tool_call(tool_call)
¶
Log a tool execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_call
|
ToolCallRecord
|
Tool call record to log |
required |
Source code in src/harombe/security/audit_db.py
log_security_decision(decision)
¶
Log a security decision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
decision
|
SecurityDecisionRecord
|
Security decision record to log |
required |
Source code in src/harombe/security/audit_db.py
get_events_by_correlation(correlation_id)
¶
Get all events for a correlation ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
correlation_id
|
str
|
Correlation ID to query |
required |
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of event dictionaries |
Source code in src/harombe/security/audit_db.py
get_events_by_session(session_id, limit=100, offset=0)
¶
Get events for a session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str | None
|
Session ID to query (None returns all events) |
required |
limit
|
int
|
Maximum number of events to return |
100
|
offset
|
int
|
Number of events to skip |
0
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of event dictionaries |
Source code in src/harombe/security/audit_db.py
get_tool_calls(tool_name=None, start_time=None, end_time=None, limit=100)
¶
Get tool call records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str | None
|
Filter by tool name (optional) |
None
|
start_time
|
datetime | None
|
Filter by start time (optional) |
None
|
end_time
|
datetime | None
|
Filter by end time (optional) |
None
|
limit
|
int
|
Maximum number of records to return |
100
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of tool call dictionaries |
Source code in src/harombe/security/audit_db.py
get_security_decisions(decision_type=None, decision=None, limit=100)
¶
Get security decision records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
decision_type
|
str | None
|
Filter by decision type (optional) |
None
|
decision
|
SecurityDecision | None
|
Filter by decision outcome (optional) |
None
|
limit
|
int
|
Maximum number of records to return |
100
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of security decision dictionaries |
Source code in src/harombe/security/audit_db.py
get_statistics(start_time=None, end_time=None)
¶
Get audit log statistics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
datetime | None
|
Start of time range (optional) |
None
|
end_time
|
datetime | None
|
End of time range (optional) |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dictionary with statistics |
Source code in src/harombe/security/audit_db.py
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 | |
AuditEvent
¶
Bases: BaseModel
Audit event record.
Source code in src/harombe/security/audit_db.py
EventType
¶
SecurityDecision
¶
SecurityDecisionRecord
¶
Bases: BaseModel
Security decision record.
Source code in src/harombe/security/audit_db.py
ToolCallRecord
¶
Bases: BaseModel
Tool execution record.
Source code in src/harombe/security/audit_db.py
AuditLogger
¶
Async audit logger with sensitive data redaction.
Provides non-blocking audit logging with automatic correlation tracking and sensitive data redaction. Integrates with AuditDatabase for storage.
Usage
logger = AuditLogger(db_path="~/.harombe/audit.db")
Log a request¶
correlation_id = logger.start_request( actor="agent-123", tool_name="filesystem", action="read_file", metadata={"path": "/etc/passwd"} )
Log the response¶
logger.end_request( correlation_id=correlation_id, status="success", duration_ms=150 )
Source code in src/harombe/security/audit_logger.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | |
__init__(db_path='~/.harombe/audit.db', retention_days=90, redact_sensitive=True)
¶
Initialize audit logger.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
db_path
|
str
|
Path to audit database |
'~/.harombe/audit.db'
|
retention_days
|
int
|
Number of days to retain logs |
90
|
redact_sensitive
|
bool
|
If True, redact sensitive data |
True
|
Source code in src/harombe/security/audit_logger.py
start()
async
¶
stop()
async
¶
Stop async log writer.
Source code in src/harombe/security/audit_logger.py
start_request(actor, tool_name=None, action='unknown', metadata=None, session_id=None)
¶
Log the start of a request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actor
|
str
|
Agent or user identifier |
required |
tool_name
|
str | None
|
Name of tool being called |
None
|
action
|
str
|
Action being performed |
'unknown'
|
metadata
|
dict[str, Any] | None
|
Additional context |
None
|
session_id
|
str | None
|
Session identifier |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Correlation ID for this request |
Source code in src/harombe/security/audit_logger.py
end_request(correlation_id, status='success', duration_ms=None, error_message=None, metadata=None)
¶
Log the completion of a request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
correlation_id
|
str
|
Correlation ID from start_request |
required |
status
|
str
|
"success", "error", or "timeout" |
'success'
|
duration_ms
|
int | None
|
Request duration in milliseconds |
None
|
error_message
|
str | None
|
Error message if status is "error" |
None
|
metadata
|
dict[str, Any] | None
|
Additional response metadata |
None
|
Source code in src/harombe/security/audit_logger.py
log_tool_call(correlation_id, tool_name, method, parameters, result=None, error=None, duration_ms=None, container_id=None, session_id=None)
¶
Log a tool execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
correlation_id
|
str
|
Request correlation ID |
required |
tool_name
|
str
|
Name of tool |
required |
method
|
str
|
Method/function called |
required |
parameters
|
dict[str, Any]
|
Tool parameters |
required |
result
|
dict[str, Any] | None
|
Tool result |
None
|
error
|
str | None
|
Error message if failed |
None
|
duration_ms
|
int | None
|
Execution duration |
None
|
container_id
|
str | None
|
Docker container ID |
None
|
session_id
|
str | None
|
Session identifier |
None
|
Source code in src/harombe/security/audit_logger.py
log_security_decision(correlation_id, decision_type, decision, reason, actor, tool_name=None, context=None, session_id=None)
¶
Log a security decision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
correlation_id
|
str
|
Request correlation ID |
required |
decision_type
|
str
|
Type of decision (authorization, egress, etc.) |
required |
decision
|
SecurityDecision
|
Decision outcome |
required |
reason
|
str
|
Reason for decision |
required |
actor
|
str
|
Agent or user making the request |
required |
tool_name
|
str | None
|
Tool involved in decision |
None
|
context
|
dict[str, Any] | None
|
Additional context |
None
|
session_id
|
str | None
|
Session identifier |
None
|
Source code in src/harombe/security/audit_logger.py
log_error(correlation_id, actor, error_message, metadata=None, session_id=None)
¶
Log an error event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
correlation_id
|
str
|
Request correlation ID |
required |
actor
|
str
|
Agent or user identifier |
required |
error_message
|
str
|
Error description |
required |
metadata
|
dict[str, Any] | None
|
Additional context |
None
|
session_id
|
str | None
|
Session identifier |
None
|
Source code in src/harombe/security/audit_logger.py
start_request_sync(actor, tool_name=None, action='unknown', metadata=None, session_id=None)
¶
Synchronous version of start_request.
Source code in src/harombe/security/audit_logger.py
end_request_sync(correlation_id, status='success', duration_ms=None, error_message=None, metadata=None)
¶
Synchronous version of end_request.
Source code in src/harombe/security/audit_logger.py
SensitiveDataRedactor
¶
Redact sensitive information from audit logs.
Detects and redacts: - API keys and tokens - Passwords and secrets - Credit card numbers - Email addresses (optionally) - File paths with credentials
Source code in src/harombe/security/audit_logger.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
redact(text, preserve_length=False)
classmethod
¶
Redact sensitive data from text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to redact |
required |
preserve_length
|
bool
|
If True, preserve original length with asterisks |
False
|
Returns:
| Type | Description |
|---|---|
str
|
Redacted text |
Source code in src/harombe/security/audit_logger.py
redact_dict(data)
classmethod
¶
Redact sensitive data from dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict[str, Any]
|
Dictionary to redact |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Redacted dictionary (new copy) |
Source code in src/harombe/security/audit_logger.py
hash_sensitive(value)
classmethod
¶
Create a hash of sensitive value for correlation.
Useful for tracking the same credential without logging it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
str
|
Sensitive value to hash |
required |
Returns:
| Type | Description |
|---|---|
str
|
SHA256 hash (first 16 characters) |
Source code in src/harombe/security/audit_logger.py
BrowserContainerManager
¶
Manages browser automation with pre-authentication and session isolation.
Source code in src/harombe/security/browser_manager.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | |
__init__(vault_backend=None, session_timeout=300, max_actions_per_session=100, max_concurrent_sessions=5, headless=True)
¶
Initialize browser container manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vault_backend
|
VaultBackend | None
|
Credential vault for pre-authentication |
None
|
session_timeout
|
int
|
Session timeout in seconds (default: 5 min) |
300
|
max_actions_per_session
|
int
|
Max actions before session refresh |
100
|
max_concurrent_sessions
|
int
|
Max concurrent browser sessions |
5
|
headless
|
bool
|
Run browser in headless mode |
True
|
Source code in src/harombe/security/browser_manager.py
start()
async
¶
Start the browser manager and launch browser.
Source code in src/harombe/security/browser_manager.py
stop()
async
¶
Stop the browser manager and cleanup all sessions.
Source code in src/harombe/security/browser_manager.py
create_session(domain, session_id=None, auto_inject_credentials=True)
async
¶
Create a new browser session with optional pre-authentication.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
domain
|
str
|
Domain for credential lookup (e.g., "github.com") |
required |
session_id
|
str | None
|
Optional session ID (auto-generated if not provided) |
None
|
auto_inject_credentials
|
bool
|
Automatically inject credentials from vault |
True
|
Returns:
| Type | Description |
|---|---|
str
|
Session ID |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If browser not started or session limit reached |
Source code in src/harombe/security/browser_manager.py
inject_credentials(session_id, domain)
async
¶
Inject credentials into browser session.
This is the KEY SECURITY STEP - credentials are injected BEFORE the agent gains access to the browser.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session ID |
required |
domain
|
str
|
Domain for credential lookup |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if credentials were injected, False if no credentials found |
Raises:
| Type | Description |
|---|---|
ValueError
|
If session not found |
Source code in src/harombe/security/browser_manager.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | |
close_session(session_id)
async
¶
Close browser session and cleanup resources.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session ID |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If session not found |
Source code in src/harombe/security/browser_manager.py
navigate(session_id, url, wait_for='load')
async
¶
Navigate to URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session ID |
required |
url
|
str
|
URL to navigate to |
required |
wait_for
|
str
|
Wait condition ("load", "networkidle", "domcontentloaded") |
'load'
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Navigation result with accessibility snapshot |
Raises:
| Type | Description |
|---|---|
ValueError
|
If session not found or navigation fails |
Source code in src/harombe/security/browser_manager.py
get_session_info(session_id)
async
¶
Get session information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Session information dict |
Source code in src/harombe/security/browser_manager.py
list_sessions()
async
¶
List all active sessions.
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of session info dicts |
BrowserCredentials
dataclass
¶
Credentials for browser pre-authentication.
Source code in src/harombe/security/browser_manager.py
BrowserSession
dataclass
¶
Represents an active browser session.
Source code in src/harombe/security/browser_manager.py
ComplianceFramework
¶
ComplianceReport
¶
Bases: BaseModel
A complete compliance report.
Source code in src/harombe/security/compliance_reports.py
ComplianceReportGenerator
¶
Generate compliance reports from audit data.
Supports PCI DSS, GDPR, and SOC 2 compliance frameworks. Queries the AuditDatabase for relevant data and generates structured reports with control assessments.
Usage
generator = ComplianceReportGenerator(audit_db) report = generator.generate( framework=ComplianceFramework.PCI_DSS, start=datetime(2026, 1, 1), end=datetime(2026, 2, 1), ) html = generator.export_html(report)
Source code in src/harombe/security/compliance_reports.py
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | |
__init__(audit_db)
¶
Initialize compliance report generator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audit_db
|
AuditDatabase
|
AuditDatabase instance for data queries |
required |
Source code in src/harombe/security/compliance_reports.py
generate(framework, start, end)
¶
Generate a compliance report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
framework
|
ComplianceFramework
|
Compliance framework to report on |
required |
start
|
datetime
|
Report period start |
required |
end
|
datetime
|
Report period end |
required |
Returns:
| Type | Description |
|---|---|
ComplianceReport
|
ComplianceReport with sections, controls, and findings |
Source code in src/harombe/security/compliance_reports.py
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | |
export_html(report)
¶
Export report as HTML string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report
|
ComplianceReport
|
ComplianceReport to export |
required |
Returns:
| Type | Description |
|---|---|
str
|
HTML string |
Source code in src/harombe/security/compliance_reports.py
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | |
export_json(report)
¶
Export report as JSON string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report
|
ComplianceReport
|
ComplianceReport to export |
required |
Returns:
| Type | Description |
|---|---|
str
|
JSON string |
ControlAssessment
¶
Bases: BaseModel
Assessment of a single compliance control.
Source code in src/harombe/security/compliance_reports.py
ControlStatus
¶
Finding
¶
Bases: BaseModel
A compliance finding/observation.
Source code in src/harombe/security/compliance_reports.py
ReportSection
¶
Bases: BaseModel
A section within a compliance report.
Source code in src/harombe/security/compliance_reports.py
DashboardMetrics
¶
Bases: BaseModel
Complete set of dashboard metrics.
Source code in src/harombe/security/dashboard.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
to_metric_list()
¶
Convert to a list of MetricValue objects for API/WebSocket consumption.
Source code in src/harombe/security/dashboard.py
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
MetricsCache
¶
Simple TTL-based metrics cache.
Source code in src/harombe/security/dashboard.py
MetricTrend
¶
MetricValue
¶
Bases: BaseModel
A single metric value with metadata.
Source code in src/harombe/security/dashboard.py
SecurityDashboard
¶
Real-time security metrics dashboard.
Computes metrics from the AuditDatabase with caching for performance. Provides WebSocket-ready data snapshots and trend calculations.
Usage
dashboard = SecurityDashboard(audit_db)
Get current metrics¶
metrics = dashboard.get_metrics()
Get as list for API/WebSocket¶
metric_list = metrics.to_metric_list()
Get trends¶
trend = dashboard.get_trend("events", hours=24)
Source code in src/harombe/security/dashboard.py
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | |
__init__(audit_db, cache_ttl_seconds=60.0)
¶
Initialize dashboard.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audit_db
|
AuditDatabase
|
AuditDatabase instance |
required |
cache_ttl_seconds
|
float
|
Metrics cache TTL in seconds |
60.0
|
Source code in src/harombe/security/dashboard.py
get_metrics()
¶
Get current security metrics.
Uses cache if available, otherwise computes from database.
Returns:
| Type | Description |
|---|---|
DashboardMetrics
|
DashboardMetrics with current values |
Source code in src/harombe/security/dashboard.py
get_trend(metric_name, hours=24)
¶
Get a time series trend for a metric.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metric_name
|
str
|
Name of the metric (e.g., "events", "errors") |
required |
hours
|
int
|
Number of hours to include |
24
|
Returns:
| Type | Description |
|---|---|
MetricTrend
|
MetricTrend with hourly data points |
Source code in src/harombe/security/dashboard.py
get_snapshot()
¶
Get a WebSocket-ready snapshot of all dashboard data.
Returns a dictionary suitable for JSON serialization and WebSocket transmission.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dictionary with metrics and metadata |
Source code in src/harombe/security/dashboard.py
invalidate_cache()
¶
TrendPoint
¶
DockerManager
¶
Manages Docker containers for MCP capability isolation.
Source code in src/harombe/security/docker_manager.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | |
__init__()
¶
create_network(network_name='harombe-network')
async
¶
Create Docker network for capability containers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
network_name
|
str
|
Name of the Docker network |
'harombe-network'
|
Raises:
| Type | Description |
|---|---|
Exception
|
If network creation fails |
Source code in src/harombe/security/docker_manager.py
create_container(config)
async
¶
Create a new container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
ContainerConfig
|
Container configuration |
required |
Returns:
| Type | Description |
|---|---|
str
|
Container ID |
Raises:
| Type | Description |
|---|---|
Exception
|
If container creation fails |
Source code in src/harombe/security/docker_manager.py
start_container(name)
async
¶
Start a container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Container name |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Exception
|
If start fails |
Source code in src/harombe/security/docker_manager.py
stop_container(name, timeout=10)
async
¶
Stop a container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Container name |
required |
timeout
|
int
|
Seconds to wait before killing |
10
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Exception
|
If stop fails |
Source code in src/harombe/security/docker_manager.py
restart_container(name, timeout=10)
async
¶
Restart a container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Container name |
required |
timeout
|
int
|
Seconds to wait before killing |
10
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Exception
|
If restart fails |
Source code in src/harombe/security/docker_manager.py
remove_container(name, force=False)
async
¶
Remove a container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Container name |
required |
force
|
bool
|
Force removal even if running |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Exception
|
If removal fails |
Source code in src/harombe/security/docker_manager.py
get_status(name)
async
¶
Get container status.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Container name |
required |
Returns:
| Type | Description |
|---|---|
ContainerStatus
|
Container status |
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Source code in src/harombe/security/docker_manager.py
get_logs(name, tail=100)
async
¶
Get container logs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Container name |
required |
tail
|
int
|
Number of lines to return |
100
|
Returns:
| Type | Description |
|---|---|
str
|
Container logs |
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Source code in src/harombe/security/docker_manager.py
get_stats(name)
async
¶
Get container resource usage statistics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Container name |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Stats dict with CPU, memory, network usage |
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Source code in src/harombe/security/docker_manager.py
list_containers()
async
¶
List all managed containers.
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of container info dicts |
Source code in src/harombe/security/docker_manager.py
cleanup_all(force=False)
async
¶
Stop and remove all managed containers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
force
|
bool
|
Force removal even if running |
False
|
Source code in src/harombe/security/docker_manager.py
MCPGateway
¶
MCP Gateway server for routing and security enforcement.
Source code in src/harombe/security/gateway.py
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | |
__init__(host='127.0.0.1', port=8100, version='0.1.0', audit_db_path='~/.harombe/audit.db', enable_audit_logging=True, enable_hitl=False, hitl_prompt_callback=None)
¶
Initialize MCP Gateway.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
host
|
str
|
Host to bind to |
'127.0.0.1'
|
port
|
int
|
Port to listen on |
8100
|
version
|
str
|
Gateway version |
'0.1.0'
|
audit_db_path
|
str
|
Path to audit database |
'~/.harombe/audit.db'
|
enable_audit_logging
|
bool
|
Enable audit logging |
True
|
enable_hitl
|
bool
|
Enable Human-in-the-Loop approval gates |
False
|
hitl_prompt_callback
|
Any | None
|
Optional callback for prompting users for approval |
None
|
Source code in src/harombe/security/gateway.py
startup()
async
¶
Gateway startup tasks.
Source code in src/harombe/security/gateway.py
shutdown()
async
¶
Gateway shutdown tasks.
Source code in src/harombe/security/gateway.py
ApprovalDecision
dataclass
¶
Result of approval request.
Source code in src/harombe/security/hitl/core.py
ApprovalStatus
¶
Bases: StrEnum
Status of approval request.
Source code in src/harombe/security/hitl/core.py
HITLGate
¶
Human-in-the-Loop gate for operation approval.
Source code in src/harombe/security/hitl/core.py
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | |
__init__(classifier=None, auto_approve_low_risk=True, default_timeout=60)
¶
Initialize HITL gate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
classifier
|
RiskClassifier | None
|
Risk classifier for operations |
None
|
auto_approve_low_risk
|
bool
|
Auto-approve low-risk operations |
True
|
default_timeout
|
int
|
Default timeout in seconds |
60
|
Source code in src/harombe/security/hitl/core.py
check_approval(operation, user=None, prompt_callback=None)
async
¶
Check if operation requires approval and get decision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operation
|
Operation
|
The operation to check |
required |
user
|
str | None
|
User requesting the operation |
None
|
prompt_callback
|
Callable | None
|
Optional callback to prompt user |
None
|
Returns:
| Type | Description |
|---|---|
ApprovalDecision
|
Approval decision |
Source code in src/harombe/security/hitl/core.py
approve(approval_id, user, reason=None)
¶
Approve a pending operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
approval_id
|
str
|
Approval request ID |
required |
user
|
str
|
User approving the operation |
required |
reason
|
str | None
|
Optional reason for approval |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
True if approval was successful |
Source code in src/harombe/security/hitl/core.py
deny(approval_id, user, reason=None)
¶
Deny a pending operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
approval_id
|
str
|
Approval request ID |
required |
user
|
str
|
User denying the operation |
required |
reason
|
str | None
|
Optional reason for denial |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
True if denial was successful |
Source code in src/harombe/security/hitl/core.py
get_pending(approval_id)
¶
list_pending()
¶
List all pending approvals.
Source code in src/harombe/security/hitl/core.py
HITLRule
dataclass
¶
Rule for determining if approval is required.
Source code in src/harombe/security/hitl/core.py
Operation
dataclass
¶
Represents an operation requiring approval.
Source code in src/harombe/security/hitl/core.py
PendingApproval
¶
Represents a pending approval request.
Source code in src/harombe/security/hitl/core.py
__init__(approval_id, operation, risk_level, timeout)
¶
Initialize pending approval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
approval_id
|
str
|
Unique approval identifier |
required |
operation
|
Operation
|
The operation requiring approval |
required |
risk_level
|
RiskLevel
|
Risk level of the operation |
required |
timeout
|
int
|
Timeout in seconds |
required |
Source code in src/harombe/security/hitl/core.py
is_expired()
¶
wait_for_decision()
async
¶
Wait for user decision or timeout.
Source code in src/harombe/security/hitl/core.py
set_decision(decision)
¶
Set the approval decision.
Source code in src/harombe/security/hitl/core.py
RiskClassifier
¶
Classifies operations by risk level.
Source code in src/harombe/security/hitl/core.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | |
__init__(rules=None)
¶
Initialize risk classifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rules
|
list[HITLRule] | None
|
List of HITL rules for classification |
None
|
classify(operation)
¶
Classify operation risk level.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operation
|
Operation
|
The operation to classify |
required |
Returns:
| Type | Description |
|---|---|
RiskLevel
|
Risk level for the operation |
Source code in src/harombe/security/hitl/core.py
requires_approval(operation)
¶
Check if operation requires approval.
Source code in src/harombe/security/hitl/core.py
get_timeout(operation)
¶
Get timeout for operation.
Source code in src/harombe/security/hitl/core.py
RiskLevel
¶
Bases: StrEnum
Risk classification for operations.
Source code in src/harombe/security/hitl/core.py
APIApprovalPrompt
¶
API-based approval prompts (for web UI, etc.).
Source code in src/harombe/security/hitl_prompt.py
__init__()
¶
create_prompt(approval_id, operation, risk_level, timeout)
¶
Create API approval prompt data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
approval_id
|
str
|
Unique approval identifier |
required |
operation
|
Operation
|
The operation requiring approval |
required |
risk_level
|
RiskLevel
|
Risk level of the operation |
required |
timeout
|
int
|
Timeout in seconds |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dict with prompt data for API clients |
Source code in src/harombe/security/hitl_prompt.py
CLIApprovalPrompt
¶
CLI-based approval prompts.
Source code in src/harombe/security/hitl_prompt.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | |
__init__(console=None)
¶
Initialize CLI approval prompt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
console
|
Console | None
|
Rich console for output |
None
|
prompt(operation, risk_level, timeout, user='user')
async
¶
Prompt user for approval via CLI.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operation
|
Operation
|
The operation requiring approval |
required |
risk_level
|
RiskLevel
|
Risk level of the operation |
required |
timeout
|
int
|
Timeout in seconds |
required |
user
|
str
|
User being prompted |
'user'
|
Returns:
| Type | Description |
|---|---|
ApprovalDecision
|
Approval decision |
Source code in src/harombe/security/hitl_prompt.py
DotEnvLoader
¶
Secure .env file loader with secret scanning.
Loads environment variables from .env files with: - Secret detection and warnings - Variable expansion - Comment support - Secure parsing
Source code in src/harombe/security/injection.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | |
__init__(warn_on_secrets=True)
¶
Initialize .env loader.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
warn_on_secrets
|
bool
|
Warn if secrets detected in .env file |
True
|
load(env_file, override=False)
¶
Load environment variables from .env file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env_file
|
str | Path
|
Path to .env file |
required |
override
|
bool
|
Override existing environment variables |
False
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dictionary of loaded variables |
Source code in src/harombe/security/injection.py
SecretInjector
¶
Injects secrets from vault into container environments.
Workflow: 1. Read secret mapping from configuration 2. Fetch secrets from vault backend 3. Generate temporary .env file (secure permissions) 4. Mount into container at startup 5. Clean up after container stops
Source code in src/harombe/security/injection.py
__init__(vault_backend, temp_dir='/tmp/harombe-secrets')
¶
Initialize secret injector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vault_backend
|
VaultBackend
|
Vault backend instance |
required |
temp_dir
|
str
|
Directory for temporary secret files |
'/tmp/harombe-secrets'
|
Source code in src/harombe/security/injection.py
inject_secrets(container_name, secret_mapping)
async
¶
Create .env file with secrets for container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Container name (for isolation) |
required |
secret_mapping
|
dict[str, str]
|
Map of env_var_name -> vault_key |
required |
Returns:
| Type | Description |
|---|---|
Path
|
Path to generated .env file |
Example
secret_mapping = { "GITHUB_TOKEN": "github/api-token", "SLACK_WEBHOOK": "slack/webhook-url", }
Source code in src/harombe/security/injection.py
cleanup(container_name)
¶
Clean up secrets file for container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Container name |
required |
Source code in src/harombe/security/injection.py
cleanup_all()
¶
Clean up all secret files.
Source code in src/harombe/security/injection.py
SecretRotationScheduler
¶
Schedules and manages secret rotation.
Features: - Automatic rotation based on policies - Graceful rotation (no downtime) - Rotation audit trail
Source code in src/harombe/security/injection.py
__init__(vault_backend, injector)
¶
Initialize rotation scheduler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vault_backend
|
VaultBackend
|
Vault backend |
required |
injector
|
SecretInjector
|
Secret injector |
required |
Source code in src/harombe/security/injection.py
add_policy(secret_key, policy)
¶
Add rotation policy for a secret.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_key
|
str
|
Vault secret key |
required |
policy
|
str
|
Rotation policy (e.g., "30d", "90d") |
required |
Source code in src/harombe/security/injection.py
rotate_secret(secret_key, generator=None)
async
¶
Rotate a secret.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret_key
|
str
|
Vault secret key |
required |
generator
|
Callable[[], str] | None
|
Optional function to generate new secret value |
None
|
Source code in src/harombe/security/injection.py
check_and_rotate()
async
¶
Check all policies and rotate as needed.
Called periodically by background task.
Source code in src/harombe/security/injection.py
DNSResolver
¶
DNS resolver with caching for performance.
Caches domain → IP resolutions to avoid repeated lookups. Supports both A (IPv4) and AAAA (IPv6) records.
Source code in src/harombe/security/network.py
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | |
__init__(cache_ttl=300)
¶
Initialize DNS resolver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cache_ttl
|
int
|
Cache TTL in seconds (default: 5 minutes) |
300
|
resolve(domain)
¶
Resolve domain to IP addresses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
domain
|
str
|
Domain name to resolve |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of IP addresses (empty if resolution fails) |
Source code in src/harombe/security/network.py
EgressFilter
¶
Determine if an egress connection should be allowed.
Performs: - Domain allowlist checking with wildcard support - IP allowlist checking - CIDR block matching - DNS resolution and caching - Performance optimized (<1ms overhead)
Source code in src/harombe/security/network.py
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | |
__init__(policy, dns_resolver=None)
¶
Initialize egress filter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
policy
|
NetworkPolicy
|
Network policy to enforce |
required |
dns_resolver
|
DNSResolver | None
|
DNS resolver (creates new one if None) |
None
|
Source code in src/harombe/security/network.py
is_allowed(destination, port=None)
¶
Check if connection to destination is allowed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
destination
|
str
|
Domain name or IP address |
required |
port
|
int | None
|
Destination port (optional) |
None
|
Returns:
| Type | Description |
|---|---|
tuple[bool, str]
|
Tuple of (allowed: bool, reason: str) |
Source code in src/harombe/security/network.py
NetworkIsolationManager
¶
Manage Docker networks and iptables rules for container isolation.
Provides: - Custom Docker network per container - iptables-based egress filtering - DNS allowlisting - Network telemetry - Dynamic policy updates
Source code in src/harombe/security/network.py
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 | |
__init__(audit_logger=None, enable_iptables=True)
¶
Initialize network isolation manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audit_logger
|
AuditLogger | None
|
Audit logger for security decisions |
None
|
enable_iptables
|
bool
|
Enable iptables rules (requires root) |
True
|
Source code in src/harombe/security/network.py
create_isolated_network(container_name, policy)
async
¶
Create isolated Docker network for container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Name of container |
required |
policy
|
NetworkPolicy
|
Network policy to enforce |
required |
Returns:
| Type | Description |
|---|---|
str
|
Network name |
Raises:
| Type | Description |
|---|---|
Exception
|
If network creation fails |
Source code in src/harombe/security/network.py
update_policy(container_name, policy)
async
¶
Update network policy for a container dynamically.
Updates the policy without requiring container restart.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Container name |
required |
policy
|
NetworkPolicy
|
New network policy |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If container not found |
Source code in src/harombe/security/network.py
check_connection(container_name, destination, port=None)
¶
Check if a connection is allowed by policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Container attempting connection |
required |
destination
|
str
|
Destination domain/IP |
required |
port
|
int | None
|
Destination port |
None
|
Returns:
| Type | Description |
|---|---|
tuple[bool, str]
|
Tuple of (allowed: bool, reason: str) |
Source code in src/harombe/security/network.py
get_metrics(container_name)
¶
Get network metrics for a container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Container name |
required |
Returns:
| Type | Description |
|---|---|
NetworkMetrics | None
|
Network metrics or None |
Source code in src/harombe/security/network.py
get_all_metrics()
¶
Get metrics for all containers.
Returns:
| Type | Description |
|---|---|
dict[str, NetworkMetrics]
|
Dictionary of container_name -> NetworkMetrics |
get_recent_blocks(container_name=None, minutes=5)
¶
Get recent blocked connection attempts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str | None
|
Filter by container (None for all) |
None
|
minutes
|
int
|
How many minutes of history |
5
|
Returns:
| Type | Description |
|---|---|
list[ConnectionAttempt]
|
List of blocked connection attempts |
Source code in src/harombe/security/network.py
cleanup_network(container_name)
async
¶
Clean up network resources for a container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Container name |
required |
Source code in src/harombe/security/network.py
cleanup_all()
async
¶
Clean up all managed networks.
Source code in src/harombe/security/network.py
NetworkMetrics
dataclass
¶
Network usage metrics for a container.
Source code in src/harombe/security/network.py
NetworkMonitor
¶
Monitor network activity and detect suspicious patterns.
Features: - Track connection attempts - Detect suspicious patterns (port scanning, rapid failures) - Integration with audit logger - Metrics collection - Alerting
Source code in src/harombe/security/network.py
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 | |
__init__(audit_logger=None)
¶
Initialize network monitor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audit_logger
|
AuditLogger | None
|
Audit logger for security decisions |
None
|
Source code in src/harombe/security/network.py
record_connection(container_name, destination, port, allowed, reason)
¶
Record a connection attempt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Name of container |
required |
destination
|
str
|
Destination domain/IP |
required |
port
|
int | None
|
Destination port |
required |
allowed
|
bool
|
Whether connection was allowed |
required |
reason
|
str
|
Reason for allow/deny decision |
required |
Source code in src/harombe/security/network.py
get_metrics(container_name)
¶
Get network metrics for a container.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str
|
Container name |
required |
Returns:
| Type | Description |
|---|---|
NetworkMetrics | None
|
Network metrics or None if not found |
Source code in src/harombe/security/network.py
get_all_metrics()
¶
Get metrics for all containers.
Returns:
| Type | Description |
|---|---|
dict[str, NetworkMetrics]
|
Dictionary of container_name -> NetworkMetrics |
get_recent_attempts(container_name=None, minutes=5)
¶
Get recent connection attempts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container_name
|
str | None
|
Filter by container (None for all) |
None
|
minutes
|
int
|
How many minutes of history to return |
5
|
Returns:
| Type | Description |
|---|---|
list[ConnectionAttempt]
|
List of connection attempts |
Source code in src/harombe/security/network.py
NetworkPolicy
¶
Bases: BaseModel
Network egress policy for a container.
Defines what outbound network connections are allowed. Supports: - Domain allowlist with wildcards (*.github.com) - IP addresses (1.1.1.1) - CIDR blocks (192.168.0.0/16, 2001:db8::/32) - DNS resolution caching for performance - Policy validation
Source code in src/harombe/security/network.py
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
validate_policy()
¶
Validate policy configuration.
Returns:
| Type | Description |
|---|---|
list[str]
|
List of validation errors (empty if valid) |
Source code in src/harombe/security/network.py
matches_domain(domain)
¶
Check if domain matches any allowed pattern.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
domain
|
str
|
Domain to check |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if allowed, False otherwise |
Source code in src/harombe/security/network.py
matches_ip(ip)
¶
Check if IP address is allowed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ip
|
str
|
IP address to check |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if allowed, False otherwise |
Source code in src/harombe/security/network.py
FilterResult
¶
Bases: BaseModel
Result of protocol filtering.
Attributes:
| Name | Type | Description |
|---|---|---|
allowed |
bool
|
Whether the packet is allowed |
reason |
str
|
Human-readable reason for the decision |
protocol |
Protocol
|
Detected protocol |
details |
dict[str, Any]
|
Additional details about the filtering decision |
duration_ms |
float | None
|
Time taken for filtering |
Source code in src/harombe/security/protocol_filter.py
HTTPValidator
¶
Validate HTTP/HTTPS request structure and content.
Checks: - HTTP method is allowed - Required headers are present - No forbidden headers - No request smuggling indicators - No suspicious URL patterns - Header size limits
Source code in src/harombe/security/protocol_filter.py
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | |
__init__(policy)
¶
Initialize HTTP validator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
policy
|
ProtocolPolicy
|
Protocol policy to enforce |
required |
Source code in src/harombe/security/protocol_filter.py
parse_request(payload_text)
¶
Parse HTTP request from payload text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
payload_text
|
str
|
Decoded payload text |
required |
Returns:
| Type | Description |
|---|---|
HTTPRequest | None
|
Parsed HTTPRequest or None if not a valid HTTP request |
Source code in src/harombe/security/protocol_filter.py
validate(request)
¶
Validate HTTP request against policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
HTTPRequest
|
Parsed HTTP request |
required |
Returns:
| Type | Description |
|---|---|
FilterResult
|
FilterResult with validation outcome |
Source code in src/harombe/security/protocol_filter.py
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | |
Protocol
¶
Bases: StrEnum
Network protocol identifiers.
Attributes:
| Name | Type | Description |
|---|---|---|
HTTP |
Hypertext Transfer Protocol |
|
HTTPS |
HTTP over TLS |
|
DNS |
Domain Name System |
|
WEBSOCKET |
WebSocket protocol |
|
FTP |
File Transfer Protocol |
|
SSH |
Secure Shell |
|
SMTP |
Simple Mail Transfer Protocol |
|
UNKNOWN |
Unrecognized protocol |
Source code in src/harombe/security/protocol_filter.py
ProtocolFilter
¶
Protocol-aware network traffic filter.
Detects the protocol in use and enforces protocol-level policies. Only permits allowed protocols with well-formed traffic.
Example
pf = ProtocolFilter() packet = NetworkPacket( ... source_ip="10.0.0.1", ... dest_ip="203.0.113.1", ... dest_port=443, ... payload=b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n", ... ) result = pf.filter(packet) print(result.allowed) True
Source code in src/harombe/security/protocol_filter.py
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 | |
__init__(policy=None)
¶
Initialize protocol filter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
policy
|
ProtocolPolicy | None
|
Protocol policy to enforce (uses defaults if None) |
None
|
Source code in src/harombe/security/protocol_filter.py
detect_protocol(packet)
¶
Detect the protocol from a network packet.
Uses a combination of port mapping and payload inspection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
packet
|
NetworkPacket
|
Network packet to inspect |
required |
Returns:
| Type | Description |
|---|---|
Protocol
|
Detected protocol |
Source code in src/harombe/security/protocol_filter.py
filter(packet)
¶
Filter packet based on protocol policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
packet
|
NetworkPacket
|
Network packet to filter |
required |
Returns:
| Type | Description |
|---|---|
FilterResult
|
FilterResult with allow/block decision |
Source code in src/harombe/security/protocol_filter.py
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 | |
get_stats()
¶
Get filtering statistics.
Returns:
| Type | Description |
|---|---|
dict[str, int]
|
Dictionary with operation counts |
update_policy(policy)
¶
Update the filtering policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
policy
|
ProtocolPolicy
|
New protocol policy |
required |
Source code in src/harombe/security/protocol_filter.py
ProtocolPolicy
¶
Bases: BaseModel
Protocol filtering policy.
Attributes:
| Name | Type | Description |
|---|---|---|
allowed_protocols |
list[Protocol]
|
Protocols that are permitted |
allowed_http_methods |
list[str]
|
HTTP methods that are permitted |
require_host_header |
bool
|
Whether HTTP Host header is required |
block_forbidden_headers |
bool
|
Whether to block requests with forbidden headers |
detect_smuggling |
bool
|
Whether to detect HTTP request smuggling |
max_header_size |
int
|
Maximum total header size in bytes |
max_url_length |
int
|
Maximum URL length in characters |
Source code in src/harombe/security/protocol_filter.py
ExecutionResult
dataclass
¶
FileResult
dataclass
¶
InstallResult
dataclass
¶
Sandbox
dataclass
¶
Represents a gVisor sandbox instance.
Source code in src/harombe/security/sandbox_manager.py
SandboxManager
¶
Manages gVisor sandbox lifecycle and code execution.
Source code in src/harombe/security/sandbox_manager.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | |
__init__(docker_manager, runtime='runsc', max_memory_mb=512, max_cpu_cores=0.5, max_disk_mb=1024, max_execution_time=30, max_output_bytes=1048576)
¶
Initialize sandbox manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
docker_manager
|
DockerManager
|
Docker manager instance |
required |
runtime
|
str
|
Container runtime (default: runsc for gVisor) |
'runsc'
|
max_memory_mb
|
int
|
Maximum memory per sandbox (MB) |
512
|
max_cpu_cores
|
float
|
Maximum CPU cores per sandbox |
0.5
|
max_disk_mb
|
int
|
Maximum disk space per sandbox (MB) |
1024
|
max_execution_time
|
int
|
Maximum execution time per run (seconds) |
30
|
max_output_bytes
|
int
|
Maximum output size (bytes) |
1048576
|
Source code in src/harombe/security/sandbox_manager.py
start()
async
¶
stop()
async
¶
Stop the sandbox manager and cleanup all sandboxes.
Source code in src/harombe/security/sandbox_manager.py
create_sandbox(language, sandbox_id=None, network_enabled=False, allowed_domains=None)
async
¶
Create a new gVisor sandbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
language
|
str
|
Programming language (python, javascript, shell) |
required |
sandbox_id
|
str | None
|
Optional sandbox ID (generated if not provided) |
None
|
network_enabled
|
bool
|
Enable network access |
False
|
allowed_domains
|
list[str] | None
|
Allowlisted domains (when network enabled) |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Sandbox ID |
Raises:
| Type | Description |
|---|---|
ValueError
|
If language not supported or Docker not started |
Source code in src/harombe/security/sandbox_manager.py
execute_code(sandbox_id, code, timeout=None, max_memory_mb=None)
async
¶
Execute code in sandbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox_id
|
str
|
Sandbox ID |
required |
code
|
str
|
Code to execute |
required |
timeout
|
int | None
|
Execution timeout (uses default if not provided) |
None
|
max_memory_mb
|
int | None
|
Memory limit (uses default if not provided) |
None
|
Returns:
| Type | Description |
|---|---|
ExecutionResult
|
Execution result with stdout, stderr, exit_code |
Raises:
| Type | Description |
|---|---|
ValueError
|
If sandbox not found |
Source code in src/harombe/security/sandbox_manager.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | |
install_package(sandbox_id, package, registry='pypi')
async
¶
Install package in sandbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox_id
|
str
|
Sandbox ID |
required |
package
|
str
|
Package name (with optional version) |
required |
registry
|
str
|
Registry name (pypi, npm) |
'pypi'
|
Returns:
| Type | Description |
|---|---|
InstallResult
|
Installation result |
Raises:
| Type | Description |
|---|---|
ValueError
|
If sandbox not found or registry not supported |
Source code in src/harombe/security/sandbox_manager.py
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | |
write_file(sandbox_id, file_path, content)
async
¶
Write file to sandbox workspace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox_id
|
str
|
Sandbox ID |
required |
file_path
|
str
|
File path (relative to /workspace) |
required |
content
|
str
|
File content |
required |
Returns:
| Type | Description |
|---|---|
FileResult
|
Write result |
Source code in src/harombe/security/sandbox_manager.py
read_file(sandbox_id, file_path)
async
¶
Read file from sandbox workspace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox_id
|
str
|
Sandbox ID |
required |
file_path
|
str
|
File path (relative to /workspace) |
required |
Returns:
| Type | Description |
|---|---|
FileResult
|
Read result with file content |
Source code in src/harombe/security/sandbox_manager.py
list_files(sandbox_id, path='.')
async
¶
List files in sandbox workspace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox_id
|
str
|
Sandbox ID |
required |
path
|
str
|
Directory path (relative to /workspace) |
'.'
|
Returns:
| Type | Description |
|---|---|
FileResult
|
List result with file names |
Source code in src/harombe/security/sandbox_manager.py
destroy_sandbox(sandbox_id)
async
¶
Destroy sandbox and cleanup resources.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox_id
|
str
|
Sandbox ID |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If sandbox not found |
Source code in src/harombe/security/sandbox_manager.py
SecretMatch
¶
Bases: BaseModel
A detected secret in text.
Source code in src/harombe/security/secrets.py
SecretScanner
¶
Scans text for secrets and credentials.
Uses multiple detection methods: 1. Regex patterns for known secret formats 2. Entropy analysis for random-looking strings 3. Contextual clues (variable names, key-value pairs)
Source code in src/harombe/security/secrets.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | |
__init__(min_confidence=0.7, min_length=16, enable_entropy_detection=True)
¶
Initialize secret scanner.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_confidence
|
float
|
Minimum confidence threshold (0.0-1.0) |
0.7
|
min_length
|
int
|
Minimum length for entropy-based detection |
16
|
enable_entropy_detection
|
bool
|
Enable entropy analysis |
True
|
Source code in src/harombe/security/secrets.py
scan(text)
¶
Scan text for secrets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to scan |
required |
Returns:
| Type | Description |
|---|---|
list[SecretMatch]
|
List of detected secrets |
Source code in src/harombe/security/secrets.py
redact(text, replacement='[REDACTED]')
¶
Scan and redact secrets from text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to redact |
required |
replacement
|
str
|
Replacement string for secrets |
'[REDACTED]'
|
Returns:
| Type | Description |
|---|---|
str
|
Redacted text |
Source code in src/harombe/security/secrets.py
alert_if_leaked(text, source='unknown')
¶
Scan text and return alerts for any secrets found.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to scan |
required |
source
|
str
|
Source identifier for logging |
'unknown'
|
Returns:
| Type | Description |
|---|---|
list[SecretMatch]
|
List of detected secrets (empty if none found) |
Source code in src/harombe/security/secrets.py
SecretType
¶
Bases: StrEnum
Types of secrets that can be detected.
Source code in src/harombe/security/secrets.py
DatadogExporter
¶
Bases: SIEMExporter
Export events to Datadog Logs API.
Source code in src/harombe/security/siem_integration.py
format_events(events)
¶
Format events for Datadog Logs API.
Source code in src/harombe/security/siem_integration.py
ElasticsearchExporter
¶
Bases: SIEMExporter
Export events to Elasticsearch (ELK Stack).
Source code in src/harombe/security/siem_integration.py
format_events(events)
¶
Format events for Elasticsearch bulk API.
Source code in src/harombe/security/siem_integration.py
ExportResult
¶
Bases: BaseModel
Result of a SIEM export operation.
Source code in src/harombe/security/siem_integration.py
SIEMConfig
¶
Bases: BaseModel
Configuration for a SIEM exporter.
Source code in src/harombe/security/siem_integration.py
SIEMEvent
¶
Bases: BaseModel
Normalized event for SIEM export.
Source code in src/harombe/security/siem_integration.py
from_audit_event(event)
classmethod
¶
Convert an AuditEvent to a normalized SIEMEvent.
Source code in src/harombe/security/siem_integration.py
SIEMExporter
¶
Base class for SIEM exporters.
Handles format conversion and HTTP transport for a single platform.
Source code in src/harombe/security/siem_integration.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
close()
async
¶
format_events(events)
¶
Format events for the specific SIEM platform.
Must be overridden by subclasses.
get_headers()
¶
Get HTTP headers for the SIEM platform.
Must be overridden by subclasses.
get_url()
¶
send(events)
async
¶
Send events to the SIEM platform with retry logic.
Source code in src/harombe/security/siem_integration.py
SIEMIntegrator
¶
Orchestrates event forwarding to multiple SIEM platforms.
Provides buffered, batched event export with automatic flushing and retry logic for handling SIEM downtime.
Usage
configs = [ SIEMConfig(platform="splunk", endpoint="https://splunk.example.com:8088", token="my-hec-token"), SIEMConfig(platform="elasticsearch", endpoint="https://elk.example.com:9200"), ] integrator = SIEMIntegrator(configs) await integrator.start()
Export events¶
await integrator.export_event(audit_event)
Shutdown¶
await integrator.stop()
Source code in src/harombe/security/siem_integration.py
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | |
platforms
property
¶
Get list of configured platforms.
__init__(configs=None)
¶
Initialize SIEM integrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
configs
|
list[SIEMConfig] | None
|
List of SIEM configurations. Only enabled configs are used. |
None
|
Source code in src/harombe/security/siem_integration.py
start()
async
¶
Start the background flush worker.
stop()
async
¶
Stop the integrator and flush remaining events.
Source code in src/harombe/security/siem_integration.py
export_event(event)
async
¶
Buffer an audit event for export to all configured SIEMs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
AuditEvent
|
Audit event to export |
required |
Source code in src/harombe/security/siem_integration.py
export_events(events)
async
¶
Export multiple events at once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
events
|
list[AuditEvent]
|
List of audit events to export |
required |
Returns:
| Type | Description |
|---|---|
list[ExportResult]
|
List of export results per platform |
Source code in src/harombe/security/siem_integration.py
flush_all()
async
¶
Flush all buffered events to all platforms.
Returns:
| Type | Description |
|---|---|
list[ExportResult]
|
List of export results per platform |
Source code in src/harombe/security/siem_integration.py
get_stats()
¶
add_platform(config)
¶
Add a new SIEM platform at runtime.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
SIEMConfig
|
SIEM configuration to add |
required |
Source code in src/harombe/security/siem_integration.py
remove_platform(platform)
¶
Remove a SIEM platform.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
platform
|
SIEMPlatform
|
Platform to remove |
required |
Source code in src/harombe/security/siem_integration.py
SIEMPlatform
¶
SplunkExporter
¶
Bases: SIEMExporter
Export events to Splunk via HTTP Event Collector (HEC).
Source code in src/harombe/security/siem_integration.py
format_events(events)
¶
Format events for Splunk HEC batch endpoint.
Source code in src/harombe/security/siem_integration.py
EnvVarBackend
¶
Bases: VaultBackend
Environment variable backend for development.
NOT SECURE - only use for local development. Reads secrets from environment variables prefixed with HAROMBE_SECRET_.
Source code in src/harombe/security/vault.py
__init__(prefix='HAROMBE_SECRET_')
¶
Initialize environment variable backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Environment variable prefix |
'HAROMBE_SECRET_'
|
get_secret(key)
async
¶
Get secret from environment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Secret value from env var |
Source code in src/harombe/security/vault.py
set_secret(key, value, **metadata)
async
¶
Set secret in environment (runtime only).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key |
required |
value
|
str
|
Secret value |
required |
metadata
|
Any
|
Ignored |
{}
|
Source code in src/harombe/security/vault.py
delete_secret(key)
async
¶
Delete secret from environment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key |
required |
list_secrets(prefix='')
async
¶
List secrets from environment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Key prefix |
''
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of secret keys |
Source code in src/harombe/security/vault.py
rotate_secret(key)
async
¶
HashiCorpVault
¶
Bases: VaultBackend
HashiCorp Vault integration.
Supports: - KV v2 secrets engine - Token authentication (default) - AppRole authentication - Token auto-renewal
Source code in src/harombe/security/vault.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | |
__init__(vault_addr='http://127.0.0.1:8200', vault_token=None, vault_namespace=None, mount_point='secret', auto_renew=True)
¶
Initialize Vault client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vault_addr
|
str
|
Vault server address |
'http://127.0.0.1:8200'
|
vault_token
|
str | None
|
Vault token (or use VAULT_TOKEN env var) |
None
|
vault_namespace
|
str | None
|
Vault namespace (enterprise feature) |
None
|
mount_point
|
str
|
KV secrets engine mount point |
'secret'
|
auto_renew
|
bool
|
Automatically renew token |
True
|
Source code in src/harombe/security/vault.py
start()
async
¶
Start token renewal background task.
Source code in src/harombe/security/vault.py
stop()
async
¶
Stop token renewal and close client.
Source code in src/harombe/security/vault.py
get_secret(key)
async
¶
Get secret from Vault KV v2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret path (without mount point) |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Secret value or None |
Source code in src/harombe/security/vault.py
set_secret(key, value, **metadata)
async
¶
Store secret in Vault KV v2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret path |
required |
value
|
str
|
Secret value |
required |
metadata
|
Any
|
Additional metadata |
{}
|
Source code in src/harombe/security/vault.py
delete_secret(key)
async
¶
Delete secret from Vault.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret path |
required |
Source code in src/harombe/security/vault.py
list_secrets(prefix='')
async
¶
List secret keys.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Key prefix filter |
''
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of secret keys |
Source code in src/harombe/security/vault.py
rotate_secret(key)
async
¶
Rotate a secret by creating a new version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret path |
required |
Source code in src/harombe/security/vault.py
SOPSBackend
¶
Bases: VaultBackend
SOPS (Secrets OPerationS) file encryption backend.
Simpler alternative to Vault for small deployments. Uses age or GPG for encryption.
Source code in src/harombe/security/vault.py
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | |
__init__(secrets_file='~/.harombe/secrets.enc.json', key_file=None)
¶
Initialize SOPS backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secrets_file
|
str
|
Path to encrypted secrets file |
'~/.harombe/secrets.enc.json'
|
key_file
|
str | None
|
Path to age key file (default: ~/.config/sops/age/keys.txt) |
None
|
Source code in src/harombe/security/vault.py
get_secret(key)
async
¶
Get secret from encrypted file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Secret value or None |
Source code in src/harombe/security/vault.py
set_secret(key, value, **metadata)
async
¶
Store secret in encrypted file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key |
required |
value
|
str
|
Secret value |
required |
metadata
|
Any
|
Ignored for SOPS |
{}
|
Source code in src/harombe/security/vault.py
delete_secret(key)
async
¶
Delete secret.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key |
required |
Source code in src/harombe/security/vault.py
list_secrets(prefix='')
async
¶
List secret keys.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Key prefix filter |
''
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of matching keys |
Source code in src/harombe/security/vault.py
rotate_secret(key)
async
¶
Rotate secret (no-op for SOPS, just reload).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key |
required |
Source code in src/harombe/security/vault.py
VaultBackend
¶
Bases: ABC
Abstract base class for secret vault backends.
Source code in src/harombe/security/vault.py
get_secret(key)
abstractmethod
async
¶
Retrieve a secret by key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key/path |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Secret value or None if not found |
set_secret(key, value, **metadata)
abstractmethod
async
¶
Store a secret.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key/path |
required |
value
|
str
|
Secret value |
required |
metadata
|
Any
|
Additional metadata |
{}
|
delete_secret(key)
abstractmethod
async
¶
list_secrets(prefix='')
abstractmethod
async
¶
List all secret keys with optional prefix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Optional key prefix filter |
''
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of secret keys |
rotate_secret(key)
abstractmethod
async
¶
Rotate a secret (create new version).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Secret key/path |
required |
get_browser_hitl_rules()
¶
Get HITL rules for browser automation tools.
Returns:
| Type | Description |
|---|---|
list[HITLRule]
|
List of HITL rules for browser tools |
Source code in src/harombe/security/browser_risk.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |
get_sensitive_domains()
¶
Get list of sensitive domains that always require approval.
Returns:
| Type | Description |
|---|---|
list[str]
|
List of sensitive domains |
Source code in src/harombe/security/browser_risk.py
get_trusted_domains()
¶
Get list of trusted domains that don't require approval for navigation.
Users can configure this list in their harombe.yaml:
Returns:
| Type | Description |
|---|---|
list[str]
|
List of trusted domains |
Source code in src/harombe/security/browser_risk.py
create_prompt(mode='cli', console=None)
¶
Create approval prompt for specified mode.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mode
|
str
|
"cli" or "api" |
'cli'
|
console
|
Console | None
|
Optional console for CLI mode |
None
|
Returns:
| Type | Description |
|---|---|
CLIApprovalPrompt | APIApprovalPrompt
|
Approval prompt instance |
Source code in src/harombe/security/hitl_prompt.py
create_injector(provider='env', **vault_kwargs)
¶
Create a secret injector with vault backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Vault provider (vault, sops, env) |
'env'
|
vault_kwargs
|
Any
|
Vault backend configuration |
{}
|
Returns:
| Type | Description |
|---|---|
SecretInjector
|
SecretInjector instance |
Source code in src/harombe/security/injection.py
get_allowed_registries()
¶
Get allowed package registries by language.
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
Dictionary mapping language to allowed registries |
Source code in src/harombe/security/sandbox_risk.py
get_sandbox_hitl_rules()
¶
Get HITL rules for code execution sandbox tools.
Returns:
| Type | Description |
|---|---|
list[HITLRule]
|
List of HITL rules for sandbox tools |
Source code in src/harombe/security/sandbox_risk.py
create_vault_backend(provider='env', **kwargs)
¶
Create a vault backend instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Backend type (vault, sops, env) |
'env'
|
kwargs
|
Any
|
Backend-specific configuration |
{}
|
Returns:
| Type | Description |
|---|---|
VaultBackend
|
VaultBackend instance |
Raises:
| Type | Description |
|---|---|
ValueError
|
If provider is unknown |
Source code in src/harombe/security/vault.py
options: show_root_heading: true show_if_no_docstring: false members_order: source
Privacy¶
Privacy-preserving routing for hybrid local/cloud AI.
harombe.privacy
¶
Privacy-preserving routing for hybrid local/cloud AI.
The Privacy Router classifies query sensitivity, detects and redacts PII, sanitizes context, and routes to either a local or cloud LLM backend. From the Agent's perspective, it is just another LLM client.
Three routing modes are supported:
local-only- All queries stay on local hardware (maximum privacy)hybrid(default) - Sensitive queries stay local, others may use cloudcloud-assisted- Cloud used freely, PII still redacted
Components:
- :class:
PrivacyRouter- Main router implementing the LLM client interface - :class:
SensitivityClassifier- Classifies query sensitivity level - :class:
ContextSanitizer- Detects and redacts PII before cloud calls
SensitivityClassifier
¶
Classifies text sensitivity for privacy-aware routing.
Source code in src/harombe/privacy/classifier.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
__init__(custom_patterns=None, custom_restricted_keywords=None, secret_scanner=None)
¶
Initialize the sensitivity classifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
custom_patterns
|
dict[str, str] | None
|
Additional regex patterns {name: pattern_str} |
None
|
custom_restricted_keywords
|
list[str] | None
|
Additional restricted keywords |
None
|
secret_scanner
|
SecretScanner | None
|
SecretScanner instance (creates default if None) |
None
|
Source code in src/harombe/privacy/classifier.py
classify(query, messages=None)
¶
Classify the sensitivity of a query and conversation context.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
The latest user query |
required |
messages
|
list[Message] | None
|
Full conversation history (optional) |
None
|
Returns:
| Type | Description |
|---|---|
SensitivityResult
|
SensitivityResult with level, reasons, and detected entities |
Source code in src/harombe/privacy/classifier.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |
PIIEntity
dataclass
¶
A detected PII entity with location information.
Source code in src/harombe/privacy/models.py
PrivacyRoutingDecision
dataclass
¶
Record of a routing decision for audit purposes.
Source code in src/harombe/privacy/models.py
RoutingMode
¶
RoutingTarget
¶
SanitizationMap
dataclass
¶
Mapping of placeholders to original values for response reconstruction.
Source code in src/harombe/privacy/models.py
SensitivityLevel
¶
Bases: Enum
Classification of query sensitivity.
Source code in src/harombe/privacy/models.py
SensitivityResult
dataclass
¶
Result of sensitivity classification.
Source code in src/harombe/privacy/models.py
PrivacyRouter
¶
LLM client that routes queries based on privacy classification.
Implements the LLMClient protocol so it can be used as a drop-in replacement for OllamaClient or any other LLM client.
Source code in src/harombe/privacy/router.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
__init__(local_client, cloud_client, mode=RoutingMode.HYBRID, classifier=None, sanitizer=None, audit_logger=None, reconstruct_responses=True)
¶
Initialize privacy router.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
local_client
|
OllamaClient
|
Local LLM client (Ollama) |
required |
cloud_client
|
AnthropicClient
|
Cloud LLM client (Anthropic) |
required |
mode
|
RoutingMode
|
Routing mode |
HYBRID
|
classifier
|
SensitivityClassifier | None
|
Sensitivity classifier (creates default if None) |
None
|
sanitizer
|
ContextSanitizer | None
|
Context sanitizer (creates default if None) |
None
|
audit_logger
|
PrivacyAuditLogger | None
|
Privacy audit logger (creates default if None) |
None
|
reconstruct_responses
|
bool
|
Whether to restore original values in cloud responses |
True
|
Source code in src/harombe/privacy/router.py
complete(messages, tools=None, temperature=None, max_tokens=None)
async
¶
Route and complete a request based on privacy classification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
max_tokens
|
int | None
|
Maximum tokens to generate |
None
|
Returns:
| Type | Description |
|---|---|
CompletionResponse
|
CompletionResponse from the appropriate backend |
Source code in src/harombe/privacy/router.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
stream_complete(messages, tools=None, temperature=None)
async
¶
Stream a completion with privacy routing.
For stream mode, sanitization reconstruction is not supported (placeholders would need to be detected mid-stream). Falls back to local if sanitization would be needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[str]
|
Content chunks as strings |
Source code in src/harombe/privacy/router.py
get_stats()
¶
Get routing statistics.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dict with routing counts and current mode |
Source code in src/harombe/privacy/router.py
ContextSanitizer
¶
Sanitizes messages by replacing sensitive entities with placeholders.
Source code in src/harombe/privacy/sanitizer.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | |
sanitize_messages(messages, entities)
¶
Sanitize a list of messages by replacing detected entities.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation messages to sanitize |
required |
entities
|
list[PIIEntity]
|
PII entities detected by the classifier |
required |
Returns:
| Type | Description |
|---|---|
tuple[list[Message], SanitizationMap]
|
Tuple of (sanitized messages, sanitization map for reconstruction) |
Source code in src/harombe/privacy/sanitizer.py
reconstruct_response(response, san_map)
¶
Restore original values in a cloud LLM response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
CompletionResponse
|
Cloud LLM response with placeholders |
required |
san_map
|
SanitizationMap
|
Sanitization map from sanitize_messages() |
required |
Returns:
| Type | Description |
|---|---|
CompletionResponse
|
Response with placeholders replaced by original values |
Source code in src/harombe/privacy/sanitizer.py
create_privacy_router(config)
¶
Factory function that creates the appropriate LLM client.
If mode is "local-only" (the default), returns a raw OllamaClient with zero overhead. Otherwise wraps OllamaClient + AnthropicClient in a PrivacyRouter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
HarombeConfig
|
HarombeConfig instance |
required |
Returns:
| Type | Description |
|---|---|
OllamaClient | PrivacyRouter
|
An LLM client (OllamaClient or PrivacyRouter) |
Source code in src/harombe/privacy/router.py
options: show_root_heading: true members_order: source
Tools¶
Built-in tool implementations: shell, filesystem, web search, browser.
harombe.tools
¶
Built-in tool implementations for harombe agents.
Tools are registered via the @tool decorator and provide agents with
capabilities like shell execution, file operations, web search, and
browser automation. Tools declare whether they are dangerous (requiring
user confirmation) and expose JSON Schema for LLM function calling.
Available tools:
- shell - Execute shell commands (dangerous)
- read_file / write_file - Filesystem operations
- web_search - DuckDuckGo search (no API key required)
- browser - Playwright-based browser automation (Phase 4.6)
Usage::
from harombe.tools.registry import get_enabled_tools
tools = get_enabled_tools(shell=True, filesystem=True, web_search=True)
options: show_root_heading: true members_order: source
Voice¶
Speech-to-text (Whisper) and text-to-speech (Piper, Coqui) capabilities.
harombe.voice
¶
Voice capabilities for harombe (STT, TTS, VAD, voice client).
Provides speech-to-text via Whisper (tiny to large-v3 models) and text-to-speech via Piper (fast, all Python versions) or Coqui (high-quality, Python <3.11 only). Includes energy-based Voice Activity Detection (VAD) for hands-free operation. Supports push-to-talk voice interaction and REST/WebSocket streaming APIs.
Components:
- :class:
WhisperSTT- Speech-to-text with faster-whisper - :class:
PiperTTS- Fast text-to-speech engine - :class:
CoquiTTS- High-quality text-to-speech (Python <3.11) - :class:
VoiceActivityDetector- Energy-based VAD for speech boundary detection
CoquiTTS
¶
Bases: TTSEngine
Coqui TTS-based text-to-speech engine.
Coqui TTS provides high-quality speech synthesis with support for multiple languages, voices, and even voice cloning.
Source code in src/harombe/voice/coqui.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
available_voices
property
¶
Return list of available voice names.
sample_rate
property
¶
Return the sample rate of generated audio.
engine_name
property
¶
Return the name of the TTS engine.
__init__(model_name='tts_models/en/ljspeech/tacotron2-DDC', device='cpu', vocoder=None)
¶
Initialize Coqui TTS engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Coqui TTS model path |
'tts_models/en/ljspeech/tacotron2-DDC'
|
device
|
Literal['cpu', 'cuda']
|
Device to run inference on |
'cpu'
|
vocoder
|
str | None
|
Optional vocoder model (auto-selected if None) |
None
|
Source code in src/harombe/voice/coqui.py
synthesize(text, voice='default', speed=1.0)
async
¶
Convert text to audio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to convert to speech |
required |
voice
|
str
|
Speaker name (if multi-speaker model) |
'default'
|
speed
|
float
|
Speech speed multiplier (0.5-2.0) |
1.0
|
Returns:
| Type | Description |
|---|---|
bytes
|
Audio data in WAV format |
Source code in src/harombe/voice/coqui.py
synthesize_stream(text, voice='default', speed=1.0)
async
¶
Stream audio generation.
Note: Coqui TTS doesn't have native streaming support, so this generates the full audio then yields it in chunks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to convert to speech |
required |
voice
|
str
|
Speaker name (if multi-speaker model) |
'default'
|
speed
|
float
|
Speech speed multiplier |
1.0
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[bytes]
|
Audio chunks |
Source code in src/harombe/voice/coqui.py
PiperTTS
¶
Bases: TTSEngine
Piper-based text-to-speech engine.
Piper is a fast, local TTS system that uses ONNX models for inference. It provides good quality with very low latency (100-300ms for short phrases).
Source code in src/harombe/voice/piper.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | |
available_voices
property
¶
Return list of available voice names.
Note: Piper models are voice-specific, so this returns the current model.
sample_rate
property
¶
Return the sample rate of generated audio.
engine_name
property
¶
Return the name of the TTS engine.
__init__(model='en_US-lessac-medium', device='cpu', download_root=None)
¶
Initialize Piper TTS engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Piper model name (e.g., "en_US-lessac-medium") |
'en_US-lessac-medium'
|
device
|
Literal['cpu', 'cuda']
|
Device to run inference on (Piper uses ONNX, limited GPU support) |
'cpu'
|
download_root
|
str | Path | None
|
Directory to download models to |
None
|
Source code in src/harombe/voice/piper.py
synthesize(text, voice='default', speed=1.0)
async
¶
Convert text to audio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to convert to speech |
required |
voice
|
str
|
Unused for Piper (model determines voice) |
'default'
|
speed
|
float
|
Speech speed multiplier (0.5-2.0) |
1.0
|
Returns:
| Type | Description |
|---|---|
bytes
|
Audio data in WAV format |
Source code in src/harombe/voice/piper.py
synthesize_stream(text, voice='default', speed=1.0)
async
¶
Stream audio generation with sentence-level chunking.
Splits text into sentences and synthesizes each independently, yielding audio as soon as each sentence is ready. This reduces time-to-first-audio compared to synthesizing the full text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to convert to speech |
required |
voice
|
str
|
Unused for Piper (model determines voice) |
'default'
|
speed
|
float
|
Speech speed multiplier |
1.0
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[bytes]
|
Audio chunks in WAV format (header first, then PCM data) |
Source code in src/harombe/voice/piper.py
STTEngine
¶
Bases: Protocol
Protocol for speech-to-text engines.
Source code in src/harombe/voice/stt.py
model_name
property
¶
Return the name of the STT model being used.
transcribe(audio, language=None)
async
¶
Transcribe audio to text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audio
|
bytes
|
Audio data in WAV format (16kHz, mono) |
required |
language
|
str | None
|
Optional language code (e.g., "en", "es"). None for auto-detect. |
None
|
Returns:
| Type | Description |
|---|---|
TranscriptionResult
|
Transcription result with text and metadata |
Source code in src/harombe/voice/stt.py
transcribe_stream(audio_stream)
¶
Stream transcription in real-time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audio_stream
|
AsyncIterator[bytes]
|
Async iterator of audio chunks |
required |
Yields:
| Type | Description |
|---|---|
AsyncIterator[str]
|
Partial transcription results as they become available |
Source code in src/harombe/voice/stt.py
TranscriptionResult
dataclass
¶
Result of speech-to-text transcription.
Source code in src/harombe/voice/stt.py
TTSEngine
¶
Bases: Protocol
Protocol for text-to-speech engines.
Source code in src/harombe/voice/tts.py
available_voices
property
¶
Return list of available voice names.
sample_rate
property
¶
Return the sample rate of generated audio.
engine_name
property
¶
Return the name of the TTS engine.
synthesize(text, voice='default', speed=1.0)
async
¶
Convert text to audio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to convert to speech |
required |
voice
|
str
|
Voice name or ID to use |
'default'
|
speed
|
float
|
Speech speed multiplier (0.5-2.0) |
1.0
|
Returns:
| Type | Description |
|---|---|
bytes
|
Audio data in WAV format |
Source code in src/harombe/voice/tts.py
synthesize_stream(text, voice='default', speed=1.0)
¶
Stream audio generation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to convert to speech |
required |
voice
|
str
|
Voice name or ID to use |
'default'
|
speed
|
float
|
Speech speed multiplier (0.5-2.0) |
1.0
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[bytes]
|
Audio chunks as they are generated |
Source code in src/harombe/voice/tts.py
VADConfig
dataclass
¶
Configuration for voice activity detection.
Attributes:
| Name | Type | Description |
|---|---|---|
energy_threshold |
float
|
RMS energy threshold for speech (0.0-1.0 normalized). Lower values are more sensitive. Default 0.01 works well for typical microphone input. |
speech_pad_ms |
int
|
Milliseconds of silence to keep before speech start. |
silence_duration_ms |
int
|
Milliseconds of silence before declaring speech end. |
min_speech_duration_ms |
int
|
Minimum speech duration to emit (filters clicks/noise). |
Source code in src/harombe/voice/vad.py
VADEvent
dataclass
¶
VADState
¶
VoiceActivityDetector
¶
Energy-based voice activity detector.
Detects speech boundaries by monitoring RMS energy levels of audio frames. Emits events when speech starts/stops and passes through speech audio.
Usage::
vad = VoiceActivityDetector()
for event in vad.process_frame(audio_frame):
if event.type == "speech_start":
# User started speaking
...
elif event.type == "speech_audio":
# Audio data during speech
...
elif event.type == "speech_end":
# User stopped speaking, event.audio has complete utterance
...
Source code in src/harombe/voice/vad.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | |
state
property
¶
Current VAD state.
reset()
¶
process_frame(frame)
¶
Process a single audio frame and return any events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
bytes
|
Raw audio frame (16kHz, 16-bit mono PCM). Should be FRAME_BYTES (960) bytes for a 30ms frame. Larger frames are processed in FRAME_BYTES chunks. |
required |
Returns:
| Type | Description |
|---|---|
list[VADEvent]
|
List of VADEvents (may be empty if no state change). |
Source code in src/harombe/voice/vad.py
WhisperSTT
¶
Bases: STTEngine
Whisper-based speech-to-text engine using faster-whisper.
faster-whisper is a reimplementation of OpenAI's Whisper model using CTranslate2, which is up to 4x faster than the original implementation with lower memory usage.
Source code in src/harombe/voice/whisper.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
model_name
property
¶
Return the name of the STT model being used.
__init__(model_size='medium', device='auto', compute_type='float16', download_root=None)
¶
Initialize Whisper STT engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_size
|
Literal['tiny', 'base', 'small', 'medium', 'large-v3']
|
Size of Whisper model to use |
'medium'
|
device
|
Literal['cpu', 'cuda', 'auto']
|
Device to run inference on |
'auto'
|
compute_type
|
Literal['int8', 'float16', 'float32']
|
Compute type for inference (lower = faster but less accurate) |
'float16'
|
download_root
|
str | Path | None
|
Directory to download models to (default: ~/.cache/huggingface) |
None
|
Source code in src/harombe/voice/whisper.py
transcribe(audio, language=None)
async
¶
Transcribe audio to text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audio
|
bytes
|
Audio data (WAV format, 16kHz mono recommended) |
required |
language
|
str | None
|
Optional language code (e.g., "en", "es"). None for auto-detect. |
None
|
Returns:
| Type | Description |
|---|---|
TranscriptionResult
|
Transcription result with text and metadata |
Source code in src/harombe/voice/whisper.py
transcribe_stream(audio_stream)
async
¶
Stream transcription using VAD-based speech boundary detection.
Uses Voice Activity Detection to segment audio into utterances and transcribes each utterance as soon as it ends. This reduces latency compared to fixed-size buffering and avoids wasting compute on silence.
Falls back to time-based buffering (1.5s) if no speech boundaries are detected, ensuring partial results are still emitted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audio_stream
|
AsyncIterator[bytes]
|
Async iterator of audio chunks (16kHz, 16-bit mono) |
required |
Yields:
| Type | Description |
|---|---|
AsyncIterator[str]
|
Transcription text for each detected utterance |
Source code in src/harombe/voice/whisper.py
create_coqui_tts(model_name='tts_models/en/ljspeech/tacotron2-DDC', device='cpu')
¶
Factory function to create a Coqui TTS engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Coqui TTS model path |
'tts_models/en/ljspeech/tacotron2-DDC'
|
device
|
str
|
Device to run on ("cpu" or "cuda") |
'cpu'
|
Returns:
| Type | Description |
|---|---|
CoquiTTS
|
Configured CoquiTTS instance |
Popular Coqui models
- tts_models/en/ljspeech/tacotron2-DDC (default, good quality)
- tts_models/en/vctk/vits (multi-speaker, high quality)
- tts_models/en/ljspeech/fast_pitch (fast, good quality)
Source code in src/harombe/voice/coqui.py
create_piper_tts(model='en_US-lessac-medium', device='cpu')
¶
Factory function to create a Piper TTS engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Piper model name |
'en_US-lessac-medium'
|
device
|
str
|
Device to run on ("cpu" or "cuda") |
'cpu'
|
Returns:
| Type | Description |
|---|---|
PiperTTS
|
Configured PiperTTS instance |
Popular Piper models
- en_US-lessac-medium (default, good quality, fast)
- en_US-lessac-high (better quality, slower)
- en_US-amy-medium (female voice)
- en_GB-alan-medium (British accent)
Source code in src/harombe/voice/piper.py
create_whisper_stt(model_size='medium', device='auto', compute_type='float16')
¶
Factory function to create a Whisper STT engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_size
|
str
|
Size of Whisper model ("tiny", "base", "small", "medium", "large-v3") |
'medium'
|
device
|
str
|
Device to run on ("cpu", "cuda", "auto") |
'auto'
|
compute_type
|
str
|
Compute type ("int8", "float16", "float32") |
'float16'
|
Returns:
| Type | Description |
|---|---|
WhisperSTT
|
Configured WhisperSTT instance |
Source code in src/harombe/voice/whisper.py
options: show_root_heading: true members_order: source
LLM Clients¶
LLM backend abstraction: Ollama, Anthropic, remote nodes.
harombe.llm
¶
LLM client implementations.
AnthropicClient
¶
LLM client for the Anthropic Messages API.
Source code in src/harombe/llm/anthropic.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
__init__(api_key, model='claude-sonnet-4-20250514', max_tokens=4096, timeout=120, temperature=0.7)
¶
Initialize Anthropic client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str
|
Anthropic API key |
required |
model
|
str
|
Model name (e.g., "claude-sonnet-4-20250514") |
'claude-sonnet-4-20250514'
|
max_tokens
|
int
|
Default max tokens for responses |
4096
|
timeout
|
int
|
Request timeout in seconds |
120
|
temperature
|
float
|
Default sampling temperature |
0.7
|
Source code in src/harombe/llm/anthropic.py
complete(messages, tools=None, temperature=None, max_tokens=None)
async
¶
Generate a completion from Anthropic Claude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
max_tokens
|
int | None
|
Maximum tokens to generate |
None
|
Returns:
| Type | Description |
|---|---|
CompletionResponse
|
CompletionResponse with content and optional tool calls |
Source code in src/harombe/llm/anthropic.py
stream_complete(messages, tools=None, temperature=None)
async
¶
Stream a completion from Anthropic Claude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[str]
|
Content chunks as strings |
Source code in src/harombe/llm/anthropic.py
CompletionResponse
dataclass
¶
LLMClient
¶
Bases: Protocol
Protocol for LLM client implementations.
Source code in src/harombe/llm/client.py
complete(messages, tools=None, temperature=None, max_tokens=None)
async
¶
Generate a completion from the LLM.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
max_tokens
|
int | None
|
Maximum tokens to generate |
None
|
Returns:
| Type | Description |
|---|---|
CompletionResponse
|
CompletionResponse with content and optional tool calls |
Source code in src/harombe/llm/client.py
stream_complete(messages, tools=None, temperature=None)
async
¶
Stream a completion from the LLM.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
Yields:
| Type | Description |
|---|---|
Any
|
Content chunks as they arrive |
Source code in src/harombe/llm/client.py
Message
dataclass
¶
A message in the conversation.
Source code in src/harombe/llm/client.py
ToolCall
dataclass
¶
OllamaClient
¶
LLM client that wraps Ollama's OpenAI-compatible API.
Source code in src/harombe/llm/ollama.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
__init__(model, base_url='http://localhost:11434/v1', timeout=120, temperature=0.7)
¶
Initialize Ollama client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Model name (e.g., "qwen2.5:7b") |
required |
base_url
|
str
|
Ollama OpenAI-compatible endpoint |
'http://localhost:11434/v1'
|
timeout
|
int
|
Request timeout in seconds |
120
|
temperature
|
float
|
Default sampling temperature |
0.7
|
Source code in src/harombe/llm/ollama.py
complete(messages, tools=None, temperature=None, max_tokens=None)
async
¶
Generate a completion from Ollama.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
max_tokens
|
int | None
|
Maximum tokens to generate |
None
|
Returns:
| Type | Description |
|---|---|
CompletionResponse
|
CompletionResponse with content and optional tool calls |
Source code in src/harombe/llm/ollama.py
stream_complete(messages, tools=None, temperature=None)
async
¶
Stream a completion from Ollama.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
Conversation history |
required |
tools
|
list[dict[str, Any]] | None
|
Available tools in OpenAI function format |
None
|
temperature
|
float | None
|
Sampling temperature override |
None
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[str]
|
Content chunks as strings |
Source code in src/harombe/llm/ollama.py
options: show_root_heading: true members_order: source